#include "sample2d.h"
#include <iostream>
#include "teflon/core/events.h"

bool log_events(teflon::EventType type, void* sender, void* listener, void* context)
{
    // this should be set in the application2d layer
    // add an intermediate layer for handling events.
    if (type == teflon::EventType::EVENT_MOUSE_MOVE)
    {
        float* data = (float*)context;
        // std::cout << "mouse position: " << data[0] << ", " << data[1] << std::endl;
    }
    else if (type == teflon::EventType::EVENT_KEY_PRESSED)
    {
        uint32_t* data = (uint32_t*)context;
        int key = int(data[0]);
        std::cout << key << std::endl;
    }

    return true;
}

void create_sprites(std::vector<teflon::ColoredQuad>& sprites, uint32_t num_quads)
{
    sprites.resize(num_quads);
    for (uint32_t idx = 0; idx < num_quads; ++idx)
    {
        sprites[idx].pos = { teflon::RNG::random(-1.0f, 1.0f), teflon::RNG::random(-1.0f, 1.0f) };
        sprites[idx].size = { teflon::RNG::random(0.0f, 0.3f), teflon::RNG::random(0.0f, 0.3f) };
        sprites[idx].color = { teflon::RNG::random(), teflon::RNG::random(), teflon::RNG::random(), 1.0f };
    }
}

Sample2d::Sample2d(const teflon::AppInfo2d& info)
    : Application2d(info)
{
    // register events
    teflon::register_event(teflon::EventType::EVENT_MOUSE_MOVE, this, log_events);
    teflon::register_event(teflon::EventType::EVENT_KEY_PRESSED, this, log_events);

    // events should be registered before window creation.
    InitWindow();

    renderer = std::make_shared<teflon::SpriteRenderer>();
    font_renderer = std::make_shared<teflon::BFontRenderer>();
    ui_renderer = std::make_shared<teflon::UILayer>();

    auto windowHandle = window->GetHandle();
    ui_renderer->Initialize(windowHandle);

    // render scene
    // teflon::Environment2D env2d;
    env2d.camera = std::make_shared<teflon::Camera2D>();
    env2d.window_width = window->GetWidth();
    env2d.window_height = window->GetHeight();

    // create scene
    sprite1 = teflon::ColoredQuad(
        glm::vec2(0.1, 0.1),
        glm::vec2(0.2, 0.2),
        glm::vec4(0.3, 0.3, 0.7, 1.0));

    sprite2 = teflon::ColoredQuad(
        glm::vec2(0.3, 0.3),
        glm::vec2(0.4, 0.4),
        glm::vec4(0.3, 0.7, 0.2, 1.0));

    sprite3 = teflon::SpriteQuad(
        glm::vec2(-0.3, -0.3),
        glm::vec2(0.3, 0.3),
        teflon::get_asset_path("textures/skybox/+x.png")
    );

    sprite4 = teflon::AnimatedSprite(
        glm::vec2(0.5, -0.5),
        glm::vec2(0.2, 0.2),
        teflon::get_asset_path("textures/walk.png"),
        4, 1
    );

    // create_sprites(sprites, 10000);

    // font and text
    // std::string font_path = teflon::get_asset_path("fonts/OpenSans-Regular.ttf");
    // std::string text("Hello");
}


void Sample2d::Update()
{
    // catch events

}


void Sample2d::RenderScene()
{
    timer.Start();
    // sprite rendering
    // std::cout << "offsetx: " << camera2d_offset_x << ", offsety: " << camera2d_offset_y << std::endl;
    env2d.camera->moveTo(camera2d_offset_x, camera2d_offset_y);

    renderer->Begin(env2d);

    renderer->Draw(sprite1);
    renderer->Draw(sprite2);
    renderer->Draw(sprite3);
    sprite4.Update(0.005f);
    renderer->Draw(sprite4);

    // for (auto& s : sprites)
    //     renderer->Draw(s);

    renderer->End();

    frame_time = timer.Stop();
}

void Sample2d::RenderUI()
{
#if 0
    // draw text
    font_renderer->Begin(font_path);
    font_renderer->Draw(text);
    font_renderer->End();
#endif

    ui_renderer->BeginFrame();
    ui_renderer->BeginWindow("camera");

    float fps = 0;
    if (frame_time > 0)
        fps = 1.0f / frame_time;
    ImGui::Text("fps: %02f", fps);

    ImGui::SliderFloat("offsetx", &camera2d_offset_x, -2.0f, 2.0f);
    ImGui::SliderFloat("offsety", &camera2d_offset_y, -2.0f, 2.0f);

    ui_renderer->EndWindow();
    ui_renderer->EndFrame();
}
